package com.meiyuetao.myt.md.entity;

import java.math.BigDecimal;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Transient;

import lab.s2jh.core.annotation.MetaData;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.meiyuetao.myt.core.entity.MytBaseEntity;

@MetaData(value = "分类")
@Entity
@Table(name = "iyb_category")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Category extends MytBaseEntity implements Comparable<Category> {
    private static final long serialVersionUID = 1L;
    @MetaData(value = "代码")
    private String categoryCode;
    @MetaData(value = "名称")
    private String name;
    @MetaData(value = "父节点")
    private Category parent;

    @MetaData(value = "子节点集合")
    private List<Category> children;
    @MetaData(value = "等级")
    private Integer categoryLevel = 1;
    @MetaData(value = "标签数据")
    private String labelData;
    @MetaData(value = "价位变化")
    private String priceRange;
    @MetaData(value = "图片")
    private String icon;
    @MetaData(value = "鼠标停留图片")
    private String hoverIcon;
    @MetaData(value = "索引号")
    private Integer orderIndex = 100;
    @MetaData(value = "备注")
    private String memo;
    @MetaData(value = "分类类型")
    private CategoryEnum categoryType;
    @MetaData(value = "关键词")
    private String keywords;
    @MetaData(value = "手机图标")
    private String mobileIcon;
    @MetaData(value = "手机 分类描述")
    private String mobileDesc;
    private BigDecimal rewardRate;

    @MetaData(value = "是否周期购")
    private Boolean circle = Boolean.FALSE;

    @MetaData(value = "站点类型")
    private SiteTypeEnum siteType = SiteTypeEnum.MYT;

    public enum SiteTypeEnum {
        @MetaData("美月淘")
        MYT,

        @MetaData("辣妈微店")
        LMVD,

        @MetaData("app内嵌优蜜")
        MEIVDAPP,

        @MetaData("积分商城")
        JFSC;
    }

    public enum CategoryEnum {
        @MetaData("分类")
        CATEGORY,

        @MetaData("标签")
        LABEL,

        @MetaData("时间轴")
        TIMELINE,

        @MetaData("主题标签")
        THEMELABEL;

    }

    @JsonProperty
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(nullable = false)
    @JsonProperty
    public Integer getCategoryLevel() {
        return categoryLevel;
    }

    public void setCategoryLevel(Integer categoryLevel) {
        this.categoryLevel = categoryLevel;
    }

    @Column(length = 1024)
    @JsonProperty
    public String getLabelData() {
        return labelData;
    }

    public void setLabelData(String labelData) {
        this.labelData = labelData;
    }

    @Column(length = 1024)
    @JsonProperty
    public String getPriceRange() {
        return priceRange;
    }

    public void setPriceRange(String priceRange) {
        this.priceRange = priceRange;
    }

    @Column(length = 512)
    public String getIcon() {
        return icon;
    }

    public void setIcon(String icon) {
        this.icon = icon;
    }

    @Column(length = 512)
    public String getHoverIcon() {
        return hoverIcon;
    }

    public void setHoverIcon(String hoverIcon) {
        this.hoverIcon = hoverIcon;
    }

    @JsonProperty
    public Integer getOrderIndex() {
        return orderIndex;
    }

    public void setOrderIndex(Integer orderIndex) {
        this.orderIndex = orderIndex;
    }

    @JsonProperty
    public String getMemo() {
        return memo;
    }

    public void setMemo(String memo) {
        this.memo = memo;
    }

    @OneToOne
    @JoinColumn(name = "parent_sid")
    public Category getParent() {
        return parent;
    }

    public void setParent(Category parent) {
        this.parent = parent;
    }

    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    @JsonProperty
    public CategoryEnum getCategoryType() {
        return categoryType;
    }

    public void setCategoryType(CategoryEnum categoryType) {
        this.categoryType = categoryType;
    }

    @Transient
    @JsonProperty
    public String getDisplay() {
        return this.getCategoryCode() + " " + this.getName();
    }

    @Transient
    @JsonIgnore
    public String getPathDisplay() {
        Category category = this;
        String label = this.getCategoryCode() + " " + this.getName();
        while (category.getParent() != null && !category.getParent().getName().equals("其他")) {
            label = (category.getParent().getCategoryCode() + " " + category.getParent().getName()) + "/" + label;
            category = category.getParent();
        }
        return label;
    }

    @Column(nullable = true, length = 32, unique = true)
    @JsonProperty
    public String getCategoryCode() {
        return categoryCode;
    }

    public void setCategoryCode(String categoryCode) {
        this.categoryCode = categoryCode;
    }

    @Transient
    public String getCategoryCodePrefix() {
        if (StringUtils.isBlank(categoryCode)) {
            return "";
        }
        String categoryCodePrefix = categoryCode;
        while (categoryCodePrefix.endsWith("0")) {
            categoryCodePrefix = StringUtils.substringBeforeLast(categoryCodePrefix, "0");
        }
        return categoryCodePrefix;
    }

    @Column(length = 2000)
    public String getKeywords() {
        return keywords;
    }

    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    @Column(length = 512)
    public String getMobileIcon() {
        return mobileIcon;
    }

    public void setMobileIcon(String mobileIcon) {
        this.mobileIcon = mobileIcon;
    }

    @Column(length = 128)
    public String getMobileDesc() {
        return mobileDesc;
    }

    public void setMobileDesc(String mobileDesc) {
        this.mobileDesc = mobileDesc;
    }

    @OneToMany(mappedBy = "parent")
    @OrderBy("orderIndex asc")
    @JsonIgnore
    public List<Category> getChildren() {
        return children;
    }

    public void setChildren(List<Category> children) {
        this.children = children;
    }

    @Column(name = "is_circle")
    public Boolean getCircle() {
        return circle;
    }

    public void setCircle(Boolean circle) {
        this.circle = circle;
    }

    @Override
    public int compareTo(Category o) {
        if (this.getOrderIndex().compareTo(o.getOrderIndex()) > 0) {
            return 1;
        } else if (this.getOrderIndex().compareTo(o.getOrderIndex()) == 0) {
            return 0;
        } else {
            return -1;
        }
    }

    /**
     * 计算节点所在层级，根节点以0开始
     * 
     * @return
     */
    @Transient
    @JsonIgnore
    public int getLevel() {
        int level = 0;
        return loopLevel(level, this);
    }

    private int loopLevel(int level, Category item) {
        Category parent = item.getParent();
        if (parent != null && parent.getId() != null) {
            return loopLevel(level + 1, item.getParent());
        }
        return level;
    }

    public BigDecimal getRewardRate() {
        return rewardRate;
    }

    public void setRewardRate(BigDecimal rewardRate) {
        this.rewardRate = rewardRate;
    }

    @Enumerated(EnumType.STRING)
    @Column(name = "site_type", length = 20)
    @JsonProperty
    public SiteTypeEnum getSiteType() {
        return siteType;
    }

    public void setSiteType(SiteTypeEnum siteType) {
        this.siteType = siteType;
    }

}